/* 工厂方法 */

pub trait Sender {
    fn send(&self, msg: &str) -> String;
}

pub trait SenderFactory {
    fn create(&self) -> Box<dyn Sender>;
}

pub struct MailSender {
    from: String
}

impl Sender for MailSender {
    fn send(&self, msg: &str) -> String {
        format!("{} 发送了邮件 : {}", &self.from, msg)
    }
}

pub struct SmsSender {
    mobile: String
}

impl Sender for SmsSender {
    fn send(&self, msg: &str) -> String {
        format!("手机号码 {} 发送了短信 : {}", &self.mobile, msg)
    }
}

pub struct MailSenderFactory {
    from: String
}

impl SenderFactory for MailSenderFactory {
    fn create(&self) -> Box<dyn Sender> {
        Box::new(
            MailSender{
                from: self.from.clone()
            }
        )
    }
}

pub struct SmsSenderFactory {
    mobile: String
}

impl SenderFactory for SmsSenderFactory {
    fn create(&self) -> Box<dyn Sender> {
        Box::new(SmsSender{
            mobile: self.mobile.clone()
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_factory_method_1() {
        let factory = MailSenderFactory {
            from: String::from("lijian@qq.com")
        };
        let sender = factory.create();
        let content = sender.send("采购合同");
        assert_eq!("lijian@qq.com 发送了邮件 : 采购合同", content);
    }

    #[test]
    fn test_factory_method_2() {
        let factory = SmsSenderFactory {
            mobile: String::from("13812345678")
        };

        let sender = factory.create();
        let content = sender.send("今天晚上吃饭");
        assert_eq!("手机号码 13812345678 发送了短信 : 今天晚上吃饭", content);
    }
}